//
// Created by root on 4/29/17.
//


#include "../runner.h"

#define OP_DECIMAL(_op,_x,_y,_z) Cell* arg_x = make_decimal(global_scheme, _x); \
    Cell* arg_y = make_decimal(global_scheme, _y); \
    Cell* ret = make_decimal(global_scheme, _z); \
    Cell* r = decimal_##_op \
    (global_scheme, arg_x, arg_y)

#define TEST_OK  assert_true(eqn(r, ret))

static void test_make_decimal() {
    Cell* d = make_decimal(global_scheme, 3.14);
    assert_string_equal(d->_type, DECIMAL_TYPE);
    assert_true(equals_double(d->_doubleValue, 3.14));
}

//decimal_add
static void test_decimal_add() {
    OP_DECIMAL(add, 0.1, 0.2, 0.3);
    TEST_OK;
}

//decimal_mul
static void test_decimal_mul() {
    OP_DECIMAL(mul, 0.1, 0.2, 0.02);
    TEST_OK;
}

//decimal_sub
static void test_decimal_sub() {
    OP_DECIMAL(sub, 0.1, 0.2, -0.1);
    TEST_OK;
}

//decimal_div
static void test_decimal_div() {
    OP_DECIMAL(div, 0.1, 0.2, 0.5);
    TEST_OK;
}

static void test_decimal_div_when_divided_by_zero() {
    Cell* arg_x = make_decimal(global_scheme, 1);
    Cell* arg_y = make_decimal(global_scheme, 0);
    Cell* r = decimal_div(global_scheme, arg_x, arg_y);
    assert_true(eqe(r, E_DIVISION_BY_ZERO));
}

//TODO
int main(int argc, char **argv) {
    const struct CMUnitTest tests[] = {
            cmocka_unit_test(test_make_decimal),
            /*int_add*/
            cmocka_unit_test(test_decimal_add),
            /*int_mul*/
            cmocka_unit_test(test_decimal_mul),
            /*int_sub*/
            cmocka_unit_test(test_decimal_sub),
            /*int_div*/
            cmocka_unit_test(test_decimal_div),
            cmocka_unit_test(test_decimal_div_when_divided_by_zero),
    };
    return cmocka_run_group_tests(tests, setup_scheme, teardown_scheme);
}
